package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.constant.JiGuangConstant;
import com.csun.cmny.core.genertor.UniqueIdGenerator;
import com.csun.cmny.provider.constant.Constant;
import com.csun.cmny.provider.model.constant.ReviseConstant;
import com.csun.cmny.provider.model.domain.OmcOrder;
import com.csun.cmny.provider.model.domain.OmcRevise;
import com.csun.cmny.provider.model.domain.OmcService;
import com.csun.cmny.provider.model.dto.SendMessageRequest;
import com.csun.cmny.provider.model.dto.SendWebSocketRequest;
import com.csun.cmny.provider.model.vo.message.FlowMessageVo;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.provider.utils.JPushService;
import com.csun.cmny.util.PublicUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.logging.log4j.message.FlowMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.activiti.engine.delegate.Expression;
import com.csun.cmny.provider.model.dto.user.UserRoleDto;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-05-30 15:17
 * @Description: the class task listener impl
 */
@Data
@Slf4j
@Component
public class TaskListenerImpl implements TaskListener, ExecutionListener {

    private Expression message;
    private String processInstanceId;
    @Autowired
    private TaskService taskService;
    @Resource
    private OmcOrderService omcOrderService;
    @Resource
    private JPushService jpushService;
    @Resource
    private UacRpcService uacRpcService;
    @Resource
    private OmcServiceService omcServiceService;
    @Autowired
    private OpcWebSocketService opcWebSocketService;
    @Resource
    private OpcMessageService opcMessageService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private OmcFlowMessageGroupService omcFlowMessageGroupService;
    @Resource
    private OmcReviseService omcReviseService;

    @Override
    public void notify(DelegateExecution delegateExecution) {
        String id = delegateExecution.getId();  // 经过的流程Id
        String msg = message.getValue(delegateExecution).toString();
        log.info("----chisj 流程监听器 = {}", message.getValue(delegateExecution));
        log.info("----chisj task listener impl delegate execution notify");
        processInstanceId = delegateExecution.getProcessInstanceId();
        log.info("----processInstanceId = {}", processInstanceId);
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
        if (PublicUtil.isEmpty(task)) {
            log.warn("流程监听器 ===》任务不存在");
            return;
        }
        Map<String, Object> variable = taskService.getVariables(task.getId());
        log.info("流程监听器 ===》variable = {}", variable);
        log.info("----delegateExecution = {}", delegateExecution);

        // 判断流程Key
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId())
                .singleResult();

        String tenantId = task.getTenantId();
        Long groupId = Long.parseLong(tenantId);
        log.info("----tenantId = {}, groupId = {}", tenantId, groupId);

        if (PublicUtil.isEmpty(processDefinition)) {
            log.warn("流程监听器 ===》流程定义不存在");
            return;
        }
        log.warn("流程监听器 ===》流程定义 = {}", processDefinition);

        String proccessKey = processDefinition.getKey();
        OmcOrder omcOrder = new OmcOrder();
        OmcService omcService = new OmcService();
        switch (proccessKey) {
            case Constant.PROCESS_KEY_ORDER :
                omcOrder = getOmcOrder();
                omcService = omcServiceService.selectByKey(omcOrder.getServiceId());
                break;
        }

        Map<String, Object> map = Maps.newHashMap();
        List<String> tagList = Lists.newArrayList();
        SendWebSocketRequest sendWebSocketRequest = new SendWebSocketRequest();
        sendWebSocketRequest.setGroupId(groupId);
        String refNo = Long.toString(UniqueIdGenerator.generateId());
        log.info("流程监听器 ===》refNo = {}", refNo);
        // sendWebSocketRequest.setRefNo(refNo);
        sendWebSocketRequest.setGroupId(groupId);

        SendMessageRequest sendMessageRequest = new SendMessageRequest();
        sendMessageRequest.setMsgCode(msg);
        sendMessageRequest.setGroupId(groupId);

        OmcRevise omcRevise = new OmcRevise();
        /**
         * 根据机构Id和code获取流程消息模板
         */
        // FlowMessageVo flowMessageVo = omcFlowMessageGroupService.queryByCodeAndGroupId(msg, groupId);

        Long applyId = 0l;

        switch (msg) {
            case Constant.ORDER_MESSAGE_WAIT :
                omcOrderService.orderWaitByProcessInstanceId(processInstanceId);
                taskService.addComment(task.getId(), processInstanceId, Constant.ORDER_MESSAGE_WAIT);

                // 根据角色查询该机构所有的用户Id
//                UserRoleDto userRoleDto = new UserRoleDto();
//                userRoleDto.setRoleCode(UacRoleCodeEnum.VOLUNTEER.getCode());
//                userRoleDto.setGroupId(omcOrder.getGroupId());
//                List<RpcUserVo> userVoList = uacRpcService.queryUserListByRoleCodeAndGroupId(userRoleDto);
//                if (PublicUtil.isEmpty(userVoList)) {
//                    return ;
//                }
//                // 查询需要推送的用户
//                for (RpcUserVo u : userVoList) {
//                    String tag = JiGuangConstant.TAG_PREFIX_USER + u.getId();
//                    tagList.add(tag);
//                }
                tagList.add(JiGuangConstant.TAG_VOLUNTEER);
                log.info("-----chisj: recv order tagList = {}", tagList);
                // 推送 -- 可以接单了
                map.put("msgType", "orderUpdate");
                map.put("oldmanName", omcOrder.getOldmanName());
                map.put("serviceName", omcService.getServiceName());
                map.put("serviceAddress", omcOrder.getServiceAddress());
                jpushService.sendToAll(Constant.ORDER_MESSAGE_WAIT,
                        Constant.ORDER_MESSAGE_WAIT,
                        Constant.ORDER_MESSAGE_WAIT, JSONObject.fromObject(map).toString(), tagList);
                break;
            case Constant.ORDER_MESSAGE_RECV_DELAY :    // 接单超时
                taskService.addComment(task.getId(), processInstanceId, Constant.ORDER_MESSAGE_RECV_DELAY);
                omcOrderService.orderRecvDelayByProcessInstanceId(processInstanceId);

                break;
            case Constant.ORDER_MESSAGE_CHECK_IN_DELAY :    // 签到超时
                taskService.addComment(task.getId(), processInstanceId, Constant.ORDER_MESSAGE_CHECK_IN_DELAY);
                omcOrderService.orderCheckInDelayByProcessInstanceId(processInstanceId);

                // 推送 -- 签到超时
                map.put("msgType", "orderUpdate");
                map.put("oldmanName", omcOrder.getOldmanName());
                map.put("serviceName", omcService.getServiceName());
                map.put("serviceAddress", omcOrder.getServiceAddress());
                tagList.add(JiGuangConstant.TAG_PREFIX_USER + omcOrder.getUserIdGet());

                log.info("-----chisj: check in order tagList = {}", tagList);
                jpushService.sendToAll(Constant.ORDER_MESSAGE_CHECK_IN_DELAY,
                        Constant.ORDER_MESSAGE_CHECK_IN_DELAY,
                        Constant.ORDER_MESSAGE_CHECK_IN_DELAY, JSONObject.fromObject(map).toString(), tagList);

                break;
            case Constant.ORDER_MESSAGE_CHECK_OUT_DELAY :   // 签退超时
                taskService.addComment(task.getId(), processInstanceId, Constant.ORDER_MESSAGE_CHECK_OUT_DELAY);
                omcOrderService.orderCheckOutDelayByProcessInstanceId(processInstanceId);

                // 推送 -- 签退超时
                map.put("msgType", "orderUpdate");
                map.put("oldmanName", omcOrder.getOldmanName());
                map.put("serviceName", omcService.getServiceName());
                map.put("serviceAddress", omcOrder.getServiceAddress());
                tagList.add(JiGuangConstant.TAG_PREFIX_USER + omcOrder.getUserIdGet());

                log.info("-----chisj: check out order tagList = {}", tagList);
                jpushService.sendToAll(Constant.ORDER_MESSAGE_CHECK_OUT_DELAY,
                        Constant.ORDER_MESSAGE_CHECK_OUT_DELAY,
                        Constant.ORDER_MESSAGE_CHECK_OUT_DELAY, JSONObject.fromObject(map).toString(), tagList);

                break;
            case Constant.ORDER_MESSAGE_CONFIRM_DELAY :     // 确认超时
                taskService.addComment(task.getId(), processInstanceId, Constant.ORDER_MESSAGE_CONFIRM_DELAY);
                omcOrderService.orderConfirmDelayByProcessInstanceId(processInstanceId);
                break;

            case ReviseConstant.REVISE_FLOW_APPLY : // 调房调级 -- 班长申请
                log.info("流程监听器 ===》调房调级 -- 班长申请");
                // 发送给角色
//                String service = variable.get(ReviseConstant.REVISE_VAR_SERVICE).toString();
//                List<String> roleList = Arrays.asList(service.split(","))
//                        .stream().map(s -> String.format(s.trim())).collect(Collectors.toList());
//                sendWebSocketRequest.setRoleCodeList(roleList);
//
//                if (PublicUtil.isNotEmpty(flowMessageVo)) {
//                    sendWebSocketRequest.setMessage(flowMessageVo.getMessage());
//                    opcWebSocketService.sendWebSocketMessage(sendWebSocketRequest);
//                }
                opcMessageService.pushWithMsgCode(sendMessageRequest);
                log.info("task name = {} ", task.getName());
                break;
            case ReviseConstant.REVISE_FLOW_SERVICE_REFUSE : // 调房调级 -- 服务部长拒绝
                log.info("流程监听器 ===》调房调级 -- 服务部长拒绝");
                // 给班组推送，服务部长拒绝了该申请
                applyId = Long.parseLong(variable.get(ReviseConstant.REVISE_VAR_APPLY).toString());
                log.info("流程监听器 ===》调房调级申请人 = {}", applyId);
//
//                sendWebSocketRequest.setUserIdList(Lists.newArrayList(applyId));
//                if (PublicUtil.isNotEmpty(flowMessageVo)) {
//                    sendWebSocketRequest.setMessage(flowMessageVo.getMessage());
//                    opcWebSocketService.sendWebSocketMessage(sendWebSocketRequest);
//                }
                /**
                 * @date    2019-12-09
                 * @author  chisj
                 * @desc    推送描述信息
                 */
                sendMessageRequest.setExtrasParam(getOmcRevise());
                tagList.add(JiGuangConstant.TAG_PREFIX_USER + applyId);
                sendMessageRequest.setTagList(tagList);
                sendMessageRequest.setUserIdList(Lists.newArrayList(applyId));
                opcMessageService.pushByUser(sendMessageRequest);
                break;
            case ReviseConstant.REVISE_FLOW_SERVICE_AGREE : // 调房调级 -- 服务部长同意
                log.info("流程监听器 ===》调房调级 -- 服务部长同意");
                // 发送给角色
//                String admit = variable.get(ReviseConstant.REVISE_VAR_ADMIT).toString();
//                List<String> admitRoleList = Arrays.asList(admit.split(","))
//                        .stream().map(s -> String.format(s.trim())).collect(Collectors.toList());
//                sendWebSocketRequest.setRoleCodeList(admitRoleList);
//                if (PublicUtil.isNotEmpty(flowMessageVo)) {
//                    sendWebSocketRequest.setMessage(flowMessageVo.getMessage());
//                    opcWebSocketService.sendWebSocketMessage(sendWebSocketRequest);
//                }
                opcMessageService.pushWithMsgCode(sendMessageRequest);
                break;
            case ReviseConstant.REVISE_FLOW_ADMIT_CONFIRM : // 调房调级 -- 接待确认
                log.info("流程监听器 ===》调房调级 -- 接待确认");
                // 根据参数获取要发送的角色
//                String charge = variable.get(ReviseConstant.REVISE_VAR_CHARGE).toString();
//                List<String> chargeRoleList = Arrays.asList(charge.split(","))
//                        .stream().map(s -> String.format(s.trim())).collect(Collectors.toList());
//                sendWebSocketRequest.setRoleCodeList(chargeRoleList);
//
//                if (PublicUtil.isNotEmpty(flowMessageVo)) {
//                    sendWebSocketRequest.setMessage(flowMessageVo.getMessage());
//                    opcWebSocketService.sendWebSocketMessage(sendWebSocketRequest);
//                }
                opcMessageService.pushWithMsgCode(sendMessageRequest);

                break;
            case ReviseConstant.REVISE_FLOW_CHARGE_CONFIRM : // 调房调级 -- 收费确认
                log.info("流程监听器 ===》调房调级 -- 收费确认");
                applyId = Long.parseLong(variable.get(ReviseConstant.REVISE_VAR_APPLY).toString());
                log.info("流程监听器 ===》调房调级申请人 = {}", applyId);
//
//                sendWebSocketRequest.setUserIdList(Lists.newArrayList(applyId));
//                if (PublicUtil.isNotEmpty(flowMessageVo)) {
//                    sendWebSocketRequest.setMessage(flowMessageVo.getMessage());
//                    opcWebSocketService.sendWebSocketMessage(sendWebSocketRequest);
//                }
                /**
                 * @date    2019-12-09
                 * @author  chisj
                 * @desc    推送描述信息
                 */
                sendMessageRequest.setExtrasParam(getOmcRevise());
                tagList.add(JiGuangConstant.TAG_PREFIX_USER + applyId);
                sendMessageRequest.setTagList(tagList);
                sendMessageRequest.setUserIdList(Lists.newArrayList(applyId));
                opcMessageService.pushByUser(sendMessageRequest);

                break;
            default:
                break;
        }
    }

    @Override
    public void notify(DelegateTask delegateTask) {
        log.info("----chisj 任务监听器 = {}", message.getValue(delegateTask));
        log.info("----chisj task listener impl delegate task notify");
        processInstanceId = delegateTask.getProcessInstanceId();
        log.info("----processInstanceId = {}", processInstanceId);
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
        log.info("----task = {}", task);
        log.info("----delegateTask = {}", delegateTask);
        //
        OmcOrder omcOrderQuery = new OmcOrder();
        omcOrderQuery.setProcessInstanceId(processInstanceId);
        omcOrderQuery = omcOrderService.selectOne(omcOrderQuery);
        omcOrderQuery.setStat(Constant.ORDER_STAT_RECV_DELAY);
        //taskService.complete(delegateTask.getId());
    }

    public OmcOrder getOmcOrder() {
        OmcOrder omcOrder = new OmcOrder();
        omcOrder.setProcessInstanceId(processInstanceId);

        return omcOrderService.selectOne(omcOrder);
    }

    public OmcRevise getOmcRevise() {
        OmcRevise omcRevise = new OmcRevise();
        omcRevise.setProcessInstanceId(processInstanceId);

        return omcReviseService.selectOne(omcRevise);
    }
}
